# -*- coding: utf-8 -*-
import signal
import os
import time
from django.test import TestCase
from django.core.urlresolvers import reverse
from django.conf import settings
from stream.selenium import selenium

from django_openid_auth import views
login_view_name = u'django_openid_auth.views.login_begin'

class LoginOverride:
    def __init__(self, post_override = None):
        self.requests = []
        if post_override is not None:
            self.post_override = post_override
        else:
            self.post_override = LoginOverride.loginByOpenID

    def __call__(self, request):
        self.requests.append(request)
        if request.method == 'GET':
            from django_openid_auth.forms import OpenIDLoginForm
            from django.shortcuts import render_to_response
            return render_to_response('openid/login.html', { 'form': OpenIDLoginForm() })
        elif request.method == 'POST':
            return self.post_override(request)

    def resetPostOverride(self):
        self.post_override = LoginOverride.loginByOpenID

    def postOverride(self, post_override):
        self.post_override = post_override

    @staticmethod
    def loginByOpenID(request):
        from django.http import HttpResponseRedirect
        from django.contrib.auth import login
        from stream import models
        openid_url = request.POST['openid_identifier']
        user = models.getOrCreateOpenIDUser(openid_url)
        login(request, user)
        return HttpResponseRedirect('/')

# A hack to let different classes set different ways of authentication
views.login_begin = LoginOverride()

class SeleniumTestBase(TestCase):
    class SeleniumSingleton:
        def __init__(self):
            import atexit
            self.sel_server_pid = os.spawnlp(os.P_NOWAIT, "java", "java", "-jar", "./stream/selenium-server.jar", "-firefoxProfileTemplate", "/home/commando/.mozilla/firefox/myx1fzcb.development")
            atexit.register(self.stop)
            self.sel = selenium("localhost", 4444, "*chrome", "http://127.0.0.1:8000/", 5)
            time.sleep(1) # Give the server some time to start
            self.sel.start()
            self.sel_started = True

        def stop(self):
            #time.sleep(1000)
            if not hasattr(self, 'stopped'):
                self.stopped = True
            if getattr(self, 'sel_started', False):
                self.sel.stop()
            os.kill(self.sel_server_pid, signal.SIGTERM)

    selenium_singleton = SeleniumSingleton()

    def __init__(self, *args, **kwargs):
        super(SeleniumTestBase, self).__init__(*args, **kwargs)
        self.sel = self.__class__.selenium_singleton.sel
        self.elements = {
            'openid_url' : 'openid_url', # Field for OpenID URL.
            'openid_login' : 'openid_login', # OpenID login by URL.
            'openid_username' : 'openid_username', # OpenID provider username field
            'openid_continue' : 'openid_continue' #OpenID login with provider.
        }

    def setUp(self):
        super(SeleniumTestBase, self).setUp()
        self.old_update_details = getattr(settings, 'OPENID_UPDATE_DETAILS_FROM_SREG', False)
        settings.OPENID_UPDATE_DETAILS_FROM_SREG = False
        self.verificationErrors = []

    def login(self, openid):
        self.sel.open(reverse('django_openid_auth.views.login_begin'))
        self.sel.type(self.elements["openid_url"], openid)
        self.sel.click(self.elements['openid_login'])
        self.sel.wait_for_page_to_load("5000")

    def tearDown(self):
        super(SeleniumTestBase, self).tearDown()
        self.sel.open(reverse('stream.views.logout'))
        settings.OPENID_UPDATE_DETAILS_FROM_SREG = self.old_update_details
        self.assertEqual([], self.verificationErrors)

class SeleniumTestLogin(SeleniumTestBase):
    def testLogin(self):
        self.login('http://example.com')
        self.sel.open('/')
        self.assertTrue(self.sel.is_text_present("You are now logged in"))

    def testHighlight(self):
        self.sel.open(reverse('django_openid_auth.views.login_begin'))
        self.assertFalse(self.sel.is_element_present('openid_highlight'))

class SeleniumTestProviders(SeleniumTestBase):
    '''
    Tests clicking on provider logos and sending data from login page.
    Directly URL resolver cache to use the necessary login function.
    '''
    class RequestStorage():
        def __init__(self):
            self.requests = []

        def __call__(self, request):
            from django.http import HttpResponseRedirect
            self.requests.append(request)
            return HttpResponseRedirect('/')

        def lastRequest(self):
            return self.requests[-1]

    def tearDown(self):
        views.login_begin.resetPostOverride()
        super(SeleniumTestProviders, self).tearDown()

    def submitProvider(self, provider_name, username = None):
        self.sel.open(reverse(login_view_name))
        self.storage = SeleniumTestProviders.RequestStorage()
        views.login_begin.postOverride(self.storage)

        self.sel.click("//a[@title='%s']" % provider_name)
        if username is not None:
            self.sel.type(self.elements["openid_username"], username)
            self.sel.click(self.elements["openid_continue"])
        self.sel.wait_for_page_to_load("5000")

    def testGoogle(self): # No username
        self.submitProvider('Google')
        self.assertEqual(self.storage.lastRequest().POST['openid_identifier'], 'https://www.google.com/accounts/o8/id')

    def testMyOpenID(self): # Requires username
        self.submitProvider('MyOpenID', 'user')
        self.assertEqual(self.storage.lastRequest().POST['openid_identifier'], 'http://user.myopenid.com/')

#class SeleniumTestAddition(SeleniumTestBase, base.LeanDbTestCase):
#    def testAddFeed(self):
#        sel = self.sel
#        self.login('user1')
#        sel.open("/1")
#        sel.click("add")
#        sel.wait_for_page_to_load("5000")
#        sel.select("type-select", "label=News feed")
#        sel.click("//option[@value='feed_form']")
#        sel.type("id_url", "http://yandex.ru")
#        sel.click("id_import_tags")
#        sel.click("id_published")
#        sel.click("message-1")
#        sel.type("id_tags", "yandex")
#        sel.click("save")
#        try: self.failUnless(sel.is_text_present("Unpublish"))
#        except AssertionError, e: self.verificationErrors.append(str(e))
#        try: self.assertEqual(u"Корпоративный блог Яндекса", sel.get_text(u"link=Корпоративный блог Яндекса"))
#        except AssertionError, e: self.verificationErrors.append(str(e))
#        try: self.assertEqual(u"Новогодний клик: что искали в первые 5 минут 2010 года", sel.get_text(u"link=Новогодний клик: что искали в первые 5 минут 2010 года"))
#        except AssertionError, e: self.verificationErrors.append(str(e))
#        sel.click("//li[3]/span[1]/a")
#        sel.click("//li[@id='subscription-1']/div[2]/span[1]")
#        sel.type("id_name", "some blog")
#        sel.type("id_tags", "new_tag")
#        sel.click("id_published")
#        sel.click("id_update")
#        sel.click("submit-subscription")
#        sel.wait_for_page_to_load("30000")
